#!/usr/bin/env python3
# -*- coding: utf-8 -*-
import os
import sys

import copy

'''
输入一个目录，计算目录中每个聚类文件的sse值
文件格式有特殊要求，可以使用目前java聚类程序产生的文件
'''

def main(argv):
    sse_dict = {}
    directory_path = "/Users/David/Desktop/实验结果-sse"
    cal_directory(directory_path, sse_dict)
    for key in sse_dict:
        print(key, ':', sse_dict[key])


def cal_directory(directory_path, sse_dict):
    files = os.listdir(directory_path)
    for file in files:
        if not file.startswith('.'):
            file = os.path.join(directory_path, file)
            if os.path.isfile(file):
                sse_dict[file] = cal_sse(file)
            else:
                cal_directory(file, sse_dict)


def cal_sse(file_path):
    # 按类读入数据为一个dict
    data = {}
    with open(file_path, 'r', encoding='utf-8') as f:
        cluster = ''
        line = f.readline().strip()
        while line:
            if line.startswith('cluster'):
                cluster = line.strip()
                data[cluster] = []
                f.readline()
                f.readline()
            else:
                if line != '\n':
                    instance = line.strip().split(',')
                    instance = list(map(float, instance))
                    data[cluster].append(instance)
            line = f.readline()
    # print('原始数据：', data)
    # 计算每个属性的极大极小值，存入list
    attr_min = {}
    attr_max = {}
    attr_list = {}
    for key in data:
        cluster = data[key]
        for instance in cluster:
            if len(attr_list) == 0:
                for index, attr in enumerate(instance):
                    attr_list[index] = []
            for index, attr in enumerate(instance):
                attr_list[index].append(attr)
    for key in attr_list:
        attr_min[key] = min(attr_list[key])
        attr_max[key] = max(attr_list[key])
    # print('属性的最小值：', attr_min)
    # print('属性的最大值：', attr_max)
    # 对所有数据进行标准化处理
    norm_data = copy.deepcopy(data)
    for key in norm_data:
        cluster = norm_data[key]
        for instance in cluster:
            for index, attr in enumerate(instance):
                normalize_attr = (attr - attr_min[index]) / (attr_max[index] - attr_min[index])
                instance[index] = normalize_attr
    # print('归一化后的数据：', norm_data)
    # 计算每个类的图心
    centroids_data = copy.deepcopy(norm_data)
    for key in centroids_data:
        cluster = centroids_data[key]
        attr_list = {}
        for instance in cluster:
            if len(attr_list) == 0:
                for index, attr in enumerate(instance):
                    attr_list[index] = []
            for index, attr in enumerate(instance):
                attr_list[index].append(attr)
        centroid = []
        for attr_index in attr_list:
            attr_mean = sum(attr_list[attr_index]) / len(attr_list[attr_index])
            centroid.append(attr_mean)
        centroids_data[key] = centroid
    # print('图心数据：', centroids_data)
    # 计算误差平方和
    sse = 0
    for key in norm_data:
        cluster = norm_data[key]
        centroid = centroids_data[key]
        cluster_sse = 0
        for instance in cluster:
            for index, attr in enumerate(instance):
                cluster_sse += (attr - centroid[index]) ** 2
        sse += cluster_sse
    # print('sse:', sse)
    return sse


if __name__ == '__main__':
    argv = sys.argv
    main(argv)
